#ifndef RBT_TEXTREADER_INCLUDE
#define RBT_TEXTREADER_INCLUDE

#include "Encoding.h"

class TextReader
{
public:
	virtual int32 ReadLine( string& value ) = 0;
	virtual int32 Read( tchar& value ) = 0;
	virtual int32 ReadToEnd( string& value ) = 0;
};


#include "IO/FileStream.h"


RETURNCODE E_STREAMREADER_INVALID_STREAM  = -24001;
RETURNCODE E_STREAMREADER_CREATE_ENCODING = -24002;
RETURNCODE E_STREAMREADER_ALLOCATE        = -24003;
RETURNCODE E_STREAMREADER_EOS             = -24004;
RETURNCODE R_STREAMREADER_NOT_EOS         = -24005;
RETURNCODE E_STREAMREADER_STREAM_READ     = -24006;
RETURNCODE E_STREAMREADER_INVALID_EOS     = -24007;
RETURNCODE E_STREAMREADER_PERAMBLE_ALLOC  = -24008;

class StreamReader :
	public TextReader
{
protected:
	bool m_userStream;
	bool m_userEncoding;

	Encoding* m_encoding;
	Stream*   m_stream;

	byte*     m_bytes;
	tchar*    m_chars;

	uint32 m_charSize;
	uint32 m_charPos;

	uint32 m_byteSize;
	uint32 m_bytePos;

	uint32 m_readSize;
	uint32 m_saveSize;

	const static uint32 MAX_READ_SIZE = 7;

	int32 Initalize();
	int32 ReadChars( uint32 offset = 0 );
	int32 ReadStream();
	bool  CheckByte( const int32& byte1 , const int32& byte2 );
	bool  CheckByte( const int32& byte1 , const int32& byte2 , const int32& byte3 );
	bool  CheckByteEx( const int32& byte1 , const int32& byte2 );
	int32 DecodeStream( bool autoReadBom );
	int32 Initalize( Stream* stream , Encoding* encoding , bool autoReadBom );
	int32 ReadBuffer();
	bool  EndStream();

public:
	StreamReader();

	int32 EndOfStream();
	int32 Read( tchar& value );
	int32 ReadToEnd( string& value );
	int32 ReadLine( string& value );
	
	int32 Initalize( cstring& path );
	int32 Initalize( cstring& path , Encoding* encoding );
	int32 Initalize( Stream* stream );
	int32 Initalize( Stream* stream , Encoding* encoding );
	int32 Uninitalize();
};

#endif